package Launcher;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import java.util.Random;
import org.junit.Test;
import sort.InsertionSort;
import sort.MergeSort;
import sort.QuickSort;
import sort.RegginSort;

public class Tester {
	long[] list;
	InsertionSort iss = new InsertionSort();
	MergeSort ms = new MergeSort();
	QuickSort qs = new QuickSort();
	RegginSort rs = new RegginSort();

	@Test
	public void makeListWithNoElements() {
		list = new long[0];
		assertEquals(list.length, 0);
	}

	@Test
	public void makeListWithOneElement() {
		list = new long[1];
		list[0] = 1;
		assertEquals(list.length, 1);
	}

	@Test
	public void makeListWithFourElements() {
		list = new long[4];
		list[0] = 1;
		list[1] = 2;
		list[2] = 3;
		list[3] = 4;
		assertEquals(list.length, 4);
	}

	@Test
	public void makeListWithNineElements() {
		list = new long[9];
		list[0] = 1;
		list[1] = 2;
		list[2] = 3;
		list[3] = 4;
		list[4] = 5;
		list[5] = 6;
		list[6] = 7;
		list[7] = 8;
		list[8] = 9;
		assertEquals(list.length, 9);
	}

	@Test
	public void makeListWithDuplicates() {
		list = new long[6];
		list[0] = 1;
		list[1] = 1;
		list[2] = 2;
		list[3] = 3;
		list[4] = 5;
		list[5] = 5;
		assertEquals(list.length, 6);

	}

	/*
	 * insertionsort algorithm
	 */
	@Test
	public void insertionSort_1() {
		makeListWithNoElements();
		shuffleList();
		long[] newList = iss.insertionSort(list);
		list = newList;
		assertEquals("", printList());
	}

	@Test
	public void insertionSort_2() {
		makeListWithOneElement();
		shuffleList();
		long[] newList = iss.insertionSort(list);
		list = newList;
		assertEquals("1, ", printList());
	}

	@Test
	public void insertionSort_3() {
		makeListWithFourElements();
		shuffleList();
		long[] newList = iss.insertionSort(list);
		list = newList;
		assertEquals("1, 2, 3, 4, ", printList());
	}

	@Test
	public void insertionSort_4() {
		makeListWithNineElements();
		shuffleList();
		long[] newList = iss.insertionSort(list);
		list = newList;
		assertEquals("1, 2, 3, 4, 5, 6, 7, 8, 9, ", printList());
	}
	
	@Test
	public void insertionSort_5() {
		makeListWithDuplicates();
		shuffleList();
		long[] newList = iss.insertionSort(list);
		list = newList;
		assertEquals("1, 1, 2, 3, 5, 5, ", printList());
	}

	/*
	 * mergesort algorithm
	 */
	@Test
	public void mergesort_1() {
		makeListWithNoElements();
		shuffleList();
		long[] newList = ms.mergeSort(list);
		list = newList;
		assertEquals("", printList());
	}

	@Test
	public void mergesort_2() {
		makeListWithOneElement();
		shuffleList();
		long[] newList = ms.mergeSort(list);
		list = newList;
		assertEquals("1, ", printList());
	}

	@Test
	public void mergesort_3() {
		makeListWithFourElements();
		shuffleList();
		long[] newList = ms.mergeSort(list);
		list = newList;
		assertEquals("1, 2, 3, 4, ", printList());
	}

	@Test
	public void mergesort_4() {
		makeListWithNineElements();
		shuffleList();
		long[] newList = ms.mergeSort(list);
		list = newList;
		assertEquals("1, 2, 3, 4, 5, 6, 7, 8, 9, ", printList());
	}
	
	@Test
	public void mergeSort_5() {
		makeListWithDuplicates();
		shuffleList();
		long[] newList = ms.mergeSort(list);
		list = newList;
		assertEquals("1, 1, 2, 3, 5, 5, ", printList());
	}
	/*
	 * quicksort algorithm
	 */
	@Test
	public void quickSortTestNull() {
		assertTrue(qs.sort(null) == null);
	}

	@Test
	public void quickSortTestEmpty() {
		makeListWithNoElements();
		shuffleList();
		long[] test = qs.sort(list);
		assertEquals(test.length, list.length);
	}

	@Test
	public void quickSortTest1() {
		makeListWithOneElement();
		shuffleList();
		long[] test = qs.sort(list);
		assertEquals(test[0], 1);
	}

	@Test
	public void quickSortTest9() {
		makeListWithNineElements();
		shuffleList();
		list = qs.sort(list);
		assertEquals("1, 2, 3, 4, 5, 6, 7, 8, 9, ", printList());
	}

	@Test
	public void quickSortTestDuplicate() {
		makeListWithDuplicates();
		shuffleList();
		list = qs.sort(list);
		assertEquals("1, 1, 2, 3, 5, 5, ", printList());
	}
	/*
	 * regginsort algorithm
	 */
	@Test
	public void regginsort_1() {
		makeListWithNoElements();
		shuffleList();
		long[] newList = rs.sort(list);
		list = newList;
		assertEquals("", printList());
	}

	@Test
	public void regginsort_2() {
		makeListWithOneElement();
		shuffleList();
		long[] newList = rs.sort(list);
		list = newList;
		assertEquals("1, ", printList());
	}

	@Test
	public void regginsort_3() {
		makeListWithFourElements();
		shuffleList();
		long[] newList = rs.sort(list);
		list = newList;
		assertEquals("1, 2, 3, 4, ", printList());
	}

	@Test
	public void regginsort_4() {
		makeListWithNineElements();
		shuffleList();
		long[] newList = rs.sort(list);
		list = newList;
		assertEquals("1, 2, 3, 4, 5, 6, 7, 8, 9, ", printList());
	}
	
	@Test
	public void regginsort_5() {
		makeListWithDuplicates();
		shuffleList();
		long[] newList = rs.sort(list);
		list = newList;
		assertEquals("1, 1, 2, 3, 5, 5, ", printList());
	}

	/*
	 * rest of the bullshit
	 */
	private String printList() {
		if (list.length == 0) {
			return "";
		}
		String tempString = "";
		for (int i = 0; i < list.length; i++) {
			tempString = tempString + list[i] + ", ";
		}
		return tempString;
	}

	public void shuffleList() {
		int n = list.length;
		Random random = new Random();
		random.nextInt();
		for (int i = 0; i < n; i++) {
			int change = i + random.nextInt(n - i);
			swap(list, i, change);
		}
	}

	private void swap(long[] a, int i, int change) {
		long helper = a[i];
		a[i] = a[change];
		a[change] = helper;
	}
}
